package com.coursehub.user.service;

import com.coursehub.user.dto.UserDTO;
import com.coursehub.user.entity.User;
import com.coursehub.user.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 * 
 * @author CourseHub Team
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    public User registerUser(User user) {
        // 如果没有设置userAccount，使用userName作为账号
        if (user.getUserAccount() == null || user.getUserAccount().trim().isEmpty()) {
            if (user.getUserName() == null || user.getUserName().trim().isEmpty()) {
                return null;
            }
            user.setUserAccount(user.getUserName());
        }
        
        // 生成用户ID
        user.setUserId("U" + user.getUserAccount());
        
        // 检查用户是否已存在（按账号或用户名）
        if (userRepository.existsByUserAccount(user.getUserAccount()) || 
            userRepository.existsByUserName(user.getUserName())) {
            return null;
        }
        
        // 加密密码
        String encodedPassword = passwordEncoder.encode(user.getUserPassword());
        user.setUserPassword(encodedPassword);
        
        // 设置默认值
        user.setIsActive(true);
        if (user.getRole() == null || user.getRole().trim().isEmpty()) {
            user.setRole("STUDENT");
        }
        
        return userRepository.save(user);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<User> authenticateUser(String username, String password) {
        // 先尝试按用户名查找
        Optional<User> userOpt = userRepository.findByUserName(username);
        
        // 如果按用户名找不到，再尝试按账号查找
        if (!userOpt.isPresent()) {
            userOpt = userRepository.findByUserAccount(username);
        }
        
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            if (user.getIsActive() && passwordEncoder.matches(password, user.getUserPassword())) {
                return Optional.of(user);
            }
        }
        return Optional.empty();
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<UserDTO> findUserById(String id) {
        return userRepository.findById(id)
                .filter(User::getIsActive)
                .map(this::convertToDTO);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<UserDTO> findUserByUsername(String username) {
        return userRepository.findByUserName(username)
                .filter(User::getIsActive)
                .map(this::convertToDTO);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<UserDTO> findUserByEmail(String email) {
        return userRepository.findByUserAccount(email)
                .filter(User::getIsActive)
                .map(this::convertToDTO);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<UserDTO> getAllUsers() {
        return userRepository.findByIsActive(true)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<UserDTO> getUsersByRole(String role) {
        return userRepository.findByRoleAndIsActive(role.toUpperCase(), true)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public Optional<UserDTO> updateUser(String id, UserDTO userDTO) {
        Optional<User> userOpt = userRepository.findById(id);
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            
            // 检查用户名和账号是否被其他用户使用
            if (!user.getUserName().equals(userDTO.getUserName()) && 
                userRepository.existsByUserName(userDTO.getUserName())) {
                throw new RuntimeException("用户名已存在: " + userDTO.getUserName());
            }
            if (!user.getUserAccount().equals(userDTO.getUserAccount()) && 
                userRepository.existsByUserAccount(userDTO.getUserAccount())) {
                throw new RuntimeException("账号已存在: " + userDTO.getUserAccount());
            }
            
            // 更新用户信息
            user.setUserName(userDTO.getUserName());
            user.setUserAccount(userDTO.getUserAccount());
            user.setRole(userDTO.getRole().toUpperCase());
            
            User updatedUser = userRepository.save(user);
            return Optional.of(convertToDTO(updatedUser));
        }
        return Optional.empty();
    }
    
    @Override
    public boolean deleteUser(String id) {
        Optional<User> userOpt = userRepository.findById(id);
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            user.setIsActive(false);
            userRepository.save(user);
            return true;
        }
        return false;
    }
    
    @Override
    public boolean toggleUserStatus(String id, boolean isActive) {
        Optional<User> userOpt = userRepository.findById(id);
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            user.setIsActive(isActive);
            userRepository.save(user);
            return true;
        }
        return false;
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean existsByUsername(String username) {
        return userRepository.existsByUserName(username);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean existsByEmail(String email) {
        return userRepository.existsByUserAccount(email);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<UserDTO> searchUsersByUsername(String username) {
        return userRepository.findByUserNameContaining(username)
                .stream()
                .filter(User::getIsActive)
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(readOnly = true)
    public long countActiveUsersByRole(String role) {
        return userRepository.countActiveUsersByRole(role.toUpperCase());
    }
    
    /**
     * 将User实体转换为UserDTO
     * @param user 用户实体
     * @return 用户DTO
     */
    private UserDTO convertToDTO(User user) {
        return new UserDTO(
                user.getUserId(),
                user.getUserName(),
                user.getUserAccount(),
                user.getRole(),
                user.getCreatedAt(),
                user.getUpdatedAt(),
                user.getIsActive()
        );
    }
}